package com.crazy.dao.sys;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

/**
 * DAO基础类——接口
 * 
 * @author Zhang Weiwei
 * @since 2013-9-8下午4:57:32
 */
@NoRepositoryBean
public interface BaseDao<Entity> extends JpaRepository<Entity, Serializable> {
	/**
	 * 删除对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:31
	 * @param entity
	 *            实体对象
	 */
	void delete(Entity entity);

	/**
	 * 按主键删除对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:37
	 * @param pk
	 *            主键
	 */
	<PK> void deleteByPK(PK pk);

	/**
	 * 分页查询所有对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-10-1下午12:33:08
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @param orders
	 *            排序
	 * @return 分页
	 */
	Page<Entity> findAll(Integer pageNum, Integer pageSize, Order... orders);

	/**
	 * @param maxRow
	 *            最大记录数
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findAll(Integer maxRow, Order... orders);

	/**
	 * 按条件查询所有对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:55:18
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findAll(Order... orders);

	/**
	 * 无分页查询对象
	 * 
	 * @author zhangweiwei
	 * @since 2013-10-30下午2:33:39
	 * @param dc
	 *            离线Criteria
	 * @param maxRow
	 *            最大记录数
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findByDetachedCriteria(DetachedCriteria dc, Integer maxRow,
			Order... orders);

	/**
	 * 无分页查询对象
	 * 
	 * @author zhangweiwei
	 * @since 2013-10-30下午2:33:39
	 * @param dc
	 *            离线Criteria
	 * @param orders
	 *            排序
	 * @return
	 */
	<T> List<T> findByDetachedCriteria(DetachedCriteria dc, Order... orders);

	/**
	 * 分页查询对象
	 * 
	 * @author zhangweiwei
	 * @since 2013-10-30下午2:31:53
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @param dc
	 *            离线Criteria
	 * @param orders
	 *            排序
	 * @return 分页
	 */
	Page<Entity> findByDetachedCriteria(Integer pageNum, Integer pageSize,
			DetachedCriteria dc, Order... orders);

	/**
	 * 按条件查询所有对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:55:30
	 * @param entity
	 *            实体对象
	 * @param excludeZeroes
	 *            排除0
	 * @param excludeNone
	 *            排除空值
	 * @param enableLike
	 *            启用模糊
	 * @param ignoreCase
	 *            忽略大小写
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findByExample(Entity entity, Boolean excludeZeroes,
			Boolean excludeNone, Boolean enableLike, Boolean ignoreCase,
			Order... orders);

	/**
	 * 按条件查询所有对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:55:21
	 * @param entity
	 *            实体对象
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findByExample(Entity entity, Order... orders);

	/**
	 * 按条件查询所有对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:55:25
	 * @param propertyName
	 *            属性名
	 * @param value
	 *            属性值
	 * @param orders
	 *            排序
	 * @return
	 */
	List<Entity> findByProperty(String propertyName, Object value,
			Order... orders);

	/**
	 * 按条件查询唯一对象
	 * 
	 * @author zhangweiwei
	 * @since 2013-11-4下午2:43:35
	 * @param dc
	 *            离线Criteria
	 * @return
	 */
	Entity findUniqueResult(DetachedCriteria dc);

	/**
	 * 按条件查询唯一对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:58
	 * @param propertyName
	 *            属性名
	 * @param value
	 *            属性值
	 * @return
	 */
	Entity findUniqueResult(String propertyName, Object value);

	/**
	 * 按条件查询所有对象（使用“in”）
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-24下午9:17:28
	 * @param propertyName
	 *            属性名
	 * @param values
	 *            属性值数组
	 * @return
	 */
	List<Entity> findUseInOfArray(String propertyName, Object... values);

	/**
	 * 按主键查询对象（立即加载）
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:41
	 * @param pk
	 *            主键
	 * @return
	 */
	Entity get(Serializable pk);

	/**
	 * @return 离线Criteria
	 */
	DetachedCriteria getDetachedCriteria();

	/**
	 * 按主键查询对象（延时加载）
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:45
	 * @param pk
	 *            主键
	 * @return
	 */
	Entity load(Serializable pk);

	/**
	 * 保存对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:48
	 * @param entity
	 *            实体对象
	 * @return
	 */
	<S extends Entity> S save(S entity);

	/**
	 * 保存或更新对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:52
	 * @param entity
	 *            实体对象
	 * @return
	 */
	Entity saveOrUpdate(Entity entity);

	/**
	 * 更新对象
	 * 
	 * @author Zhang Weiwei
	 * @since 2013-9-21下午8:54:55
	 * @param entity
	 *            实体对象
	 * @return
	 */
	Entity update(Entity entity);

	/**
	 * @param hql
	 *            Hibernate Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @return 无分页查询对象
	 */
	List<Entity> findByQuery(String hql, String[] names, Object[] values);

	/**
	 * @param hql
	 *            Hibernate Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @return 无分页查询对象
	 */
	<T> List<T> findByQuery(String hql, Map<String, Object> params);

	/**
	 * @param hql
	 *            Hibernate Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 分页
	 */
	Page<Entity> findByQuery(String hql, String[] names, Object[] values,
			Integer pageNum, Integer pageSize);

	/**
	 * @param hql
	 *            Hibernate Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 分页
	 */
	Page<Entity> findByQuery(String hql, Map<String, Object> params,
			Integer pageNum, Integer pageSize);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @return 无分页查询对象，以Object数组的形式返回查询结果。
	 */
	List<Object[]> findBySQLQuery(String sql, String[] names, Object[] values);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @return 无分页查询对象，以Object数组的形式返回查询结果。
	 */
	List<Object[]> findBySQLQuery(String sql, Map<String, Object> params);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 以Object数组的形式返回查询结果（分页）。
	 */
	Page<Object[]> findBySQLQuery(String sql, String[] names, Object[] values,
			Integer pageNum, Integer pageSize);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 以Object数组的形式返回查询结果（分页）。
	 */
	Page<Object[]> findBySQLQuery(String sql, Map<String, Object> params,
			Integer pageNum, Integer pageSize);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @return 无分页查询对象，将返回结果转换成单个实体类。
	 */
	List<Entity> findBySQLQueryToEntity(String sql, String[] names,
			Object[] values);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @return 无分页查询对象，将返回结果转换成单个实体类。
	 */
	List<Entity> findBySQLQueryToEntity(String sql, Map<String, Object> params);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param names
	 *            参数名称数组
	 * @param values
	 *            参数值数组
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 将返回结果转换成单个实体类（分页）。
	 */
	Page<Entity> findBySQLQueryToEntity(String sql, String[] names,
			Object[] values, Integer pageNum, Integer pageSize);

	/**
	 * @param sql
	 *            Structured Query Language
	 * @param params
	 *            将参数名、参数值以键值对的形式存入Map集合
	 * @param pageNum
	 *            当前页号
	 * @param pageSize
	 *            每页数量
	 * @return 将返回结果转换成单个实体类（分页）。
	 */
	Page<Entity> findBySQLQueryToEntity(String sql, Map<String, Object> params,
			Integer pageNum, Integer pageSize);
}
